package org.gd.helloconcurrent.lections;

import java.util.concurrent.TimeUnit;

public class Operations {

    public static void main(String...args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final Account a = new Account(1000);
                    final Account b = new Account(2000);

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                transfer(a, b, 500);
                            } catch (Exception e) {
                                e.printStackTrace(System.err);
                            }
                        }
                    }).start();

                    transfer(b, a, 300);
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
            }
        }).start();
    }

    public static void transfer(Account acc1, Account acc2, int amount)
        throws Exception {

        if (acc1.getBalance() < amount) {
            throw new Exception("недостаточно средств на счету");
        }
        if(acc1.getLock().tryLock(10, TimeUnit.SECONDS)) {
            try {
                if(acc2.getLock().tryLock(10, TimeUnit.SECONDS)) {
                    try {
                        acc1.withDraw(amount);
                        acc2.deposit(amount);
                        Thread.sleep(new Double(Math.random() * 1000).longValue());
                    } finally {
                        acc2.getLock().unlock();
                    }
                } else {
                    System.out.println("try lock acc2 fail");
                }
            } finally {
                acc1.getLock().unlock();
            }
        } else {
            System.out.println("try lock acc1 fail");
        }
    }

}
